package com.tipcp.quip.logging;


import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class RequestLogAspect {

    private final ObjectMapper objectMapper = new ObjectMapper();

    // 拦截所有 @RestController 下的方法（你可以按需修改）
    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void restControllerMethods() {}

    @Around("restControllerMethods()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        HttpServletRequest request = ((ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes()).getRequest();

        String uri = request.getRequestURI();
        String method = request.getMethod();
        String ip = request.getRemoteAddr();

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String controllerMethod = signature.getDeclaringTypeName() + "." + signature.getName();

        Object[] args = joinPoint.getArgs();
        String params;
        try {
            params = objectMapper.writeValueAsString(args);
        } catch (Exception e) {
            params = Arrays.toString(args);
        }

        log.info("➡️ [{}] {} | IP: {} | 方法: {} | 参数: {}", method, uri, ip, controllerMethod, params);

        Object result;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            log.error("❌ [{}] {} 调用异常: {}", method, uri, e.getMessage(), e);
            throw e;
        }

        long duration = System.currentTimeMillis() - start;

        String resultStr;
        try {
            resultStr = objectMapper.writeValueAsString(result);
        } catch (Exception e) {
            resultStr = result.toString();
        }

        log.info("✅ [{}] {} 调用完成，耗时 {}ms，返回: {}", method, uri, duration, resultStr);
        return result;
    }
}

